/**
 @file ctc_at_acl.c

 @date 2009-10-17

 @version v2.0

 The file contains acl APIs
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_const.h"
#include "ctc_linklist.h"
#include "ctc_at_acl.h"

#include "sys_usw_acl_api.h"
#include "sys_usw_common.h"
#include "sys_usw_wb_common.h"

/****************************************************************
*
* Defines and Macros
*
****************************************************************/

/***************************************************************
 *
 * Structure
 *
 ***************************************************************/

/***************************************************************
 *
 * Functions
 *
 ***************************************************************/

int32
ctc_at_acl_init(uint8 lchip, ctc_acl_global_cfg_t* acl_global_cfg)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    ctc_acl_global_cfg_t acl_cfg;

    LCHIP_CHECK(lchip);
    if (NULL == acl_global_cfg)
    {
        sal_memset(&acl_cfg, 0, sizeof(ctc_acl_global_cfg_t));
        acl_global_cfg = &acl_cfg;
    }
    
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, 1)
    {
        CTC_ERROR_RETURN(sys_usw_acl_init(lchip, acl_global_cfg));
    }

    return CTC_E_NONE;
}

int32
ctc_at_acl_deinit(uint8 lchip)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;

    LCHIP_CHECK(lchip);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, 1)
    {
        CTC_ERROR_RETURN(sys_usw_acl_deinit(lchip));
    }

    return CTC_E_NONE;
}

int32
ctc_at_acl_set_flex_key_fields(uint8 lchip, ctc_acl_flex_key_t* acl_flex_key)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;

    lchip = SYS_PP_BASE(lchip);
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip,CTC_FEATURE_ACL)
    {
        CTC_ERROR_RETURN(sys_usw_acl_set_flex_key_fields(lchip, acl_flex_key));
    }
    return CTC_E_NONE;
}
int32
ctc_at_acl_get_flex_key_fields(uint8 lchip, ctc_acl_flex_key_t* acl_flex_key)
{
    uint8 lchip_start       = lchip;
    uint8 lchip_end         = lchip + 1;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_FOREACH_LCHIP(lchip_start, lchip_end, 0)
    {
        CTC_ERROR_RETURN(sys_usw_acl_get_flex_key_fields(lchip, acl_flex_key));
    }
    return CTC_E_NONE;
}

int32
ctc_at_acl_set_aset_fields(uint8 lchip, ctc_acl_aset_t* acl_aset)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        CTC_ERROR_RETURN(sys_usw_acl_set_aset_fields(lchip, acl_aset));
    }
    return CTC_E_NONE;
}
int32
ctc_at_acl_get_aset_fields(uint8 lchip, ctc_acl_aset_t* acl_aset)
{
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_ERROR_RETURN(sys_usw_acl_get_aset_fields(lchip, acl_aset));
    return CTC_E_NONE;
}


int32
ctc_at_acl_create_presel(uint8 lchip, ctc_acl_presel_t* acl_presel)
{
    int32 ret              = 0;
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip, CTC_FEATURE_ACL)
    {
        CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_create_presel(lchip, acl_presel));
    }
    return ret;
}
int32
ctc_at_acl_destroy_presel(uint8 lchip, uint16 presel_id)
{
    int32 ret              = 0;
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip, CTC_FEATURE_ACL)
    {
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_destroy_presel(lchip, presel_id));
    }
    return ret;
}
int32
ctc_at_acl_add_presel_fields(uint8 lchip, uint16 presel_id, uint8 fields_cnt, ctc_field_key_t *fields)
{
    int32 ret = CTC_E_NONE;
    int32 ret_temp = CTC_E_NONE;
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint8 success_cnt       = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip, CTC_FEATURE_ACL)
    {
        ret_temp = sys_usw_acl_add_presel_fields(lchip, presel_id, fields_cnt, fields);
        if (CTC_E_NONE == ret_temp)
        {
            success_cnt++;
        }
        else
        {
            ret = ret_temp;
        }
    }
    return (!success_cnt? ret : CTC_E_NONE);
}
int32
ctc_at_acl_remove_presel_fields(uint8 lchip, uint16 presel_id, uint8 fields_cnt, ctc_field_key_t *fields)
{
    int32 ret               = 0;
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip, CTC_FEATURE_ACL)
    {
        CTC_AT_FOREACH_ERROR_RETURN2(ret,sys_usw_acl_remove_presel_fields(lchip, presel_id, fields_cnt, fields));
    }
    return ret;
}

int32
ctc_at_acl_create_group(uint8 lchip, uint32 group_id, ctc_acl_group_info_t* group_info)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint8 priority          = 0;
    int32 ret               = 0;
    uint8 global_pp_en    = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(group_info);   

    /* get global acl status */
    priority = (group_info->type == CTC_ACL_GROUP_TYPE_HASH) ? 0xff : group_info->priority;
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, group_info->dir, priority, &global_pp_en));
    
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_create_group(lchip, group_id, group_info);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_create_group(lchip, group_id, group_info));       
    }
   
    return ret;
}

int32
ctc_at_acl_destroy_group(uint8 lchip, uint32 group_id)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    int32 ret               = CTC_E_NONE;
    uint8 global_pp_en      = 0;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    
     /* get global acl status */
     CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_gid(lchip, group_id, &dir, &lkup_level));
     CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
       lchip = SYS_PP_BASE(lchip);
       return sys_usw_acl_destroy_group(lchip, group_id);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_destroy_group(lchip, group_id));
    }

    return ret;
}


int32
ctc_at_acl_install_group(uint8 lchip, uint32 group_id, ctc_acl_group_info_t* group_info)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_gid(lchip, group_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_install_group(lchip, group_id, group_info);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_install_group(lchip, group_id, group_info));
    }

    return ret;
}

int32
ctc_at_acl_uninstall_group(uint8 lchip, uint32 group_id)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_gid(lchip, group_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_uninstall_group(lchip, group_id);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_uninstall_group(lchip, group_id));
    }
    return ret;
}

int32
ctc_at_acl_get_group_info(uint8 lchip, uint32 group_id, ctc_acl_group_info_t* group_info)
{
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    CTC_ERROR_RETURN(sys_usw_acl_get_group_info(SYS_PP_BASE(lchip), group_id, group_info));
    
    return CTC_E_NONE;
}


int32
ctc_at_acl_add_entry(uint8 lchip, uint32 group_id, ctc_acl_entry_t* acl_entry)
{
    uint8 lchip_start       = SYS_PP_BASE(lchip);
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    uint16 bmp              = 0;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(acl_entry);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_gid(lchip, group_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));
    SYS_ACL_ENTRY_HASH_NOT_EXIST(lchip, SYS_COM_ENTRY_HASH_ACL_ENTRY, acl_entry->entry_id, pp_bmp);
    
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        ret = sys_usw_acl_add_entry(lchip, group_id, acl_entry);
        bmp = ret ? 0 : 0x01;
    }
    else
    {
        pp_bmp = SYS_PP_BMP_MAPPING(acl_entry->pp_bmp);
        CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
        {
            if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
            {
                continue;
            }
            CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_add_entry(lchip, group_id, acl_entry));
            CTC_BIT_SET(bmp, (lchip-lchip_start));
        }
    }

    if (MCHIP_FEATURE_PP_EN(lchip_start, CTC_FEATURE_ACL) && bmp)
    {
        sys_usw_acl_add_entry_hash(lchip_start, acl_entry->entry_id, bmp, SYS_COM_ENTRY_HASH_ACL_ENTRY);
    }
    return ret;
}

int32
ctc_at_acl_remove_entry(uint8 lchip, uint32 entry_id)
{
    uint8 lchip_start       = SYS_PP_BASE(lchip);
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;


    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    }
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);        
        ret = sys_usw_acl_remove_entry(lchip, entry_id);
    }
    else
    {
        CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
        {
            if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
            {
                continue;
            }
            CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_remove_entry(lchip, entry_id));
        }
    }
    if(ret == CTC_E_NONE)
    {
        sys_usw_acl_remove_entry_hash(lchip_start, entry_id, SYS_COM_ENTRY_HASH_ACL_ENTRY);
    }
    return ret;
}

int32
ctc_at_acl_install_entry(uint8 lchip, uint32 entry_id)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_install_entry(lchip, entry_id);
    }

    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_install_entry(lchip, entry_id));
    }
    return ret;
}

int32
ctc_at_acl_uninstall_entry(uint8 lchip, uint32 entry_id)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_uninstall_entry(lchip, entry_id);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_uninstall_entry(lchip, entry_id));
    }
    return ret;
}

int32
ctc_at_acl_remove_all_entry(uint8 lchip, uint32 group_id)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_gid(lchip, group_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en))

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_remove_all_entry(lchip, group_id);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_remove_all_entry(lchip, group_id));
    }
    return ret;
}

int32
ctc_at_acl_set_entry_priority(uint8 lchip, uint32 entry_id, uint32 priority)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en    = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_set_entry_priority(lchip, entry_id, priority);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_set_entry_priority(lchip, entry_id, priority));
    }
    return ret;
}

int32
ctc_at_acl_get_multi_entry(uint8 lchip, ctc_acl_query_t* query)
{    
    uint16 pp_bmp = 0, pp_id = 0;
    
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(query);
    

    if(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        pp_bmp = SYS_PP_BMP_MAPPING(query->pp_bmp);
        CTC_BIT_FIRST_VALID(pp_bmp, SYS_PP_NUM(lchip), pp_id);
        lchip = SYS_PP_BASE(lchip) + pp_id;
    }
    else
    {
        lchip = SYS_PP_BASE(lchip);
    }

    CTC_ERROR_RETURN(sys_usw_acl_get_multi_entry(lchip, query));
    return CTC_E_NONE;
}

int32
ctc_at_acl_copy_entry(uint8 lchip, ctc_acl_copy_entry_t* copy_entry)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 src_pp_bmp    = 0xFF;
    uint16 bmp          = 0;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(copy_entry);

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_copy_entry(lchip, copy_entry);
    }
    
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip, SYS_COM_ENTRY_HASH_ACL_ENTRY, copy_entry->src_entry_id, src_pp_bmp);

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(src_pp_bmp, lchip-lchip_start))
        {
            continue;
        } 
        CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_copy_entry(lchip, copy_entry));
        CTC_BIT_SET(bmp, (lchip-lchip_start));
    }
    
    if(bmp)
    {
       sys_usw_acl_add_entry_hash(lchip_start, copy_entry->dst_entry_id, bmp, SYS_COM_ENTRY_HASH_ACL_ENTRY);
    }

    return ret;
}
int32
ctc_at_acl_add_key_field(uint8 lchip, uint32 entry_id, ctc_field_key_t* key_field)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp       = 0xFF;
    int32 ret           = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;


    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_key_field(lchip, entry_id, key_field);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip - lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_add_key_field(lchip, entry_id, key_field));
    }

    return ret;
}

int32
ctc_at_acl_remove_key_field(uint8 lchip, uint32 entry_id, ctc_field_key_t* key_field)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp           = 0xFF;
    int32 ret           = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en    = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_remove_key_field(lchip, entry_id, key_field);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_remove_key_field(lchip, entry_id, key_field));
    }

    return ret;
}

int32
ctc_at_acl_add_key_field_list(uint8 lchip, uint32 entry_id, ctc_field_key_t* p_field_list, uint32* p_field_cnt)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    uint32 bkup_field_cnt = (*p_field_cnt);
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 1, 1);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        (*p_field_cnt) = bkup_field_cnt;
        CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 1, 1));
    }
    return ret;
}

int32
ctc_at_acl_remove_key_field_list(uint8 lchip, uint32 entry_id, ctc_field_key_t* p_field_list, uint32* p_field_cnt)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    uint32 bkup_field_cnt = (*p_field_cnt);
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 1, 0);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        (*p_field_cnt) = bkup_field_cnt;
        CTC_AT_FOREACH_ERROR_RETURN2(ret,sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 1, 0));
    }
    return ret;
}

int32
ctc_at_acl_add_action_field(uint8 lchip, uint32 entry_id, ctc_acl_field_action_t* action_field)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_action_field(lchip, entry_id, action_field);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_add_action_field(lchip, entry_id, action_field));
    }

    return ret;
}

int32
ctc_at_acl_add_action_field_list(uint8 lchip, uint32 entry_id, ctc_acl_field_action_t* p_field_list, uint32* p_field_cnt)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp       = 0xFF;
    uint32 bkup_field_cnt = (*p_field_cnt);
    int32 ret           = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 0, 1);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        (*p_field_cnt) = bkup_field_cnt;
        CTC_AT_FOREACH_ERROR_RETURN(ret,sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 0, 1));
    }
    return ret;
}

int32
ctc_at_acl_remove_action_field_list(uint8 lchip, uint32 entry_id, ctc_acl_field_action_t* p_field_list, uint32* p_field_cnt)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    uint32 bkup_field_cnt = (*p_field_cnt);
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 0, 0);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        (*p_field_cnt) = bkup_field_cnt;
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_add_remove_field_list(lchip, entry_id, (void*)p_field_list, p_field_cnt, 0, 0));
    }
    return ret;
}

int32
ctc_at_acl_remove_action_field(uint8 lchip, uint32 entry_id, ctc_acl_field_action_t* action_field)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0xFF;
    int32 ret               = CTC_E_NONE;
    ctc_direction_t dir     = 0;
    uint8 lkup_level        = 0;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_sys_group_info_by_eid(lchip, entry_id, &dir, &lkup_level));
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, dir, lkup_level, &global_pp_en));

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_remove_action_field(lchip, entry_id, action_field);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_ENTRY, entry_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_remove_action_field(lchip, entry_id, action_field));
    }

    return ret;
}

int32
ctc_at_acl_set_field_to_hash_field_sel(uint8 lchip, uint8 key_type, uint8 field_sel_id, ctc_field_key_t* sel_field)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip, CTC_FEATURE_ACL)
    {
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_set_field_to_hash_field_sel(lchip, key_type, field_sel_id, sel_field));
    }

    return ret;
}

int32
ctc_at_acl_add_cid_pair(uint8 lchip, ctc_acl_cid_pair_t* cid_pair)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp        = 0;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(cid_pair);

    pp_bmp = SYS_PP_BMP_MAPPING(cid_pair->pp_bmp);
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_cid_pair(lchip, cid_pair);
    }

    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip, CTC_FEATURE_ACL)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_add_cid_pair(lchip, cid_pair));
    }
 
    return ret;
}

int32
ctc_at_acl_remove_cid_pair(uint8 lchip, ctc_acl_cid_pair_t* cid_pair)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp        = 0;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(cid_pair);

    pp_bmp = SYS_PP_BMP_MAPPING(cid_pair->pp_bmp);

    CTC_AT_FOREACH_LCHIP2(lchip_start, lchip_end, all_lchip, CTC_FEATURE_ACL)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN2(ret,sys_usw_acl_remove_cid_pair(lchip, cid_pair));
    }

    return ret;
}

int32
ctc_at_acl_add_udf_entry(uint8 lchip,  ctc_acl_classify_udf_t* udf_entry)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp        = 0;
    uint16 pp_bmp_tmp        = 0;
    uint16 bmp          = 0;
    uint8 pp_base       = lchip;
    uint8 is_update     = 0;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(udf_entry);

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_udf_entry(lchip, udf_entry);
    }
    
    CTC_ERROR_RETURN(sys_usw_acl_check_udf_ad_id_mode(lchip, udf_entry)) ;

    pp_bmp = SYS_PP_BMP_MAPPING(udf_entry->pp_bmp);
    ret = sys_usw_acl_lookup_entry_hash(lchip, udf_entry->udf_id, SYS_COM_ENTRY_HASH_ACL_UDF_ENTRY, &pp_bmp_tmp);
    if ((!ret) && pp_bmp != pp_bmp_tmp)
    {
        return CTC_E_INVALID_PARAM;
    }
    else if (!ret)
    {
        is_update = 1;
    }
    ret = CTC_E_NONE;

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret ,sys_usw_acl_add_udf_entry(lchip, udf_entry));
        sys_usw_acl_count_udf_entry(pp_base, udf_entry, TRUE);
        CTC_BIT_SET(bmp, (lchip-lchip_start));   
    }
  
    if (!is_update && bmp)
    {
        sys_usw_acl_add_entry_hash(lchip_start, udf_entry->udf_id, bmp, SYS_COM_ENTRY_HASH_ACL_UDF_ENTRY);
    }
    return ret;
}

int32
ctc_at_acl_remove_udf_entry(uint8 lchip,  ctc_acl_classify_udf_t* udf_entry)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint8 pp_base       = lchip;
    uint16 pp_bmp       = 0xFF;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_remove_udf_entry(lchip, udf_entry);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_UDF_ENTRY, udf_entry->udf_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        ret = ret? ret: sys_usw_acl_remove_udf_entry(lchip, udf_entry);
        if (CTC_E_NONE == ret)
        {
            sys_usw_acl_count_udf_entry(pp_base, udf_entry, FALSE);
        }
    }
    sys_usw_acl_remove_entry_hash(lchip_start, udf_entry->udf_id, SYS_COM_ENTRY_HASH_ACL_UDF_ENTRY); 
    return ret;
}
int32
ctc_at_acl_get_udf_entry(uint8 lchip,  ctc_acl_classify_udf_t* udf_entry)
{
    uint16 pp_bmp = 0, pp_id = 0;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(udf_entry);

    if(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        if (0 == udf_entry->pp_bmp && !udf_entry->query_type)
        {
            SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_UDF_ENTRY, udf_entry->udf_id, pp_bmp);
        }
        else if (0 == udf_entry->pp_bmp )
        {
            pp_bmp = SYS_PP_BMP(lchip);
        }
        else
        {
            pp_bmp = udf_entry->pp_bmp;
        }
        CTC_BIT_FIRST_VALID(pp_bmp, SYS_PP_NUM(lchip), pp_id);
        lchip = SYS_PP_BASE(lchip) + pp_id;
    }
    else
    {
        lchip = SYS_PP_BASE(lchip);
    }

    CTC_ERROR_RETURN(sys_usw_acl_get_udf_entry(lchip, udf_entry));
    return CTC_E_NONE;
}
int32
ctc_at_acl_add_udf_entry_key_field(uint8 lchip,  uint32 udf_id, ctc_field_key_t* key_field)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp       = 0xFF;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_add_udf_entry_key_field(lchip, udf_id,key_field);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_UDF_ENTRY, udf_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_add_udf_entry_key_field(lchip, udf_id,key_field));
    }

    return ret;
}
int32
ctc_at_acl_remove_udf_entry_key_field(uint8 lchip, uint32 udf_id, ctc_field_key_t* key_field)
{
    uint8 lchip_start   = 0;
    uint8 lchip_end     = 0;
    uint8 all_lchip     = 1;
    uint16 pp_bmp       = 0xFF;
    int32 ret           = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);

    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_remove_udf_entry_key_field(lchip, udf_id,key_field);
    }
    SYS_ACL_ENTRY_HASH_ENTRY_EXIST(lchip,  SYS_COM_ENTRY_HASH_ACL_UDF_ENTRY, udf_id, pp_bmp);
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN2(ret, sys_usw_acl_remove_udf_entry_key_field(lchip, udf_id,key_field));
    }
    return ret;
}

int32
ctc_at_acl_set_league_mode(uint8 lchip, ctc_acl_league_t* league)
{
    uint8 lchip_start           = 0;
    uint8 lchip_end             = 0;
    uint8 all_lchip             = 1;
    uint16 pp_bmp               = 0;
    int32 ret                   = CTC_E_NONE;
    uint8 global_pp_en          = 0;
    uint8 pp_id                 = 0;
    uint32 global_acl_bmp       = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(league);

    pp_bmp = SYS_PP_BMP_MAPPING(league->pp_bmp);
    
    global_pp_en = league->global_pp_en;
    
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);

        /* check block valid of pp1-pp7*/
        if(global_pp_en && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
        {
            global_acl_bmp = sys_usw_acl_get_lkup_pp_en_bmp(lchip, league->dir);
            
            for (pp_id=lchip; pp_id<lchip+SYS_PP_NUM(lchip); pp_id++)
            {
                CTC_ERROR_RETURN(sys_usw_acl_check_league_block_valid(pp_id, league, global_acl_bmp));
            }
        }
        
        return sys_usw_acl_set_league_mode(lchip, league);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }

        global_acl_bmp = sys_usw_acl_get_lkup_pp_en_bmp(SYS_PP_BASE(lchip), league->dir);

        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_check_league_block_valid(SYS_PP_BASE(lchip), league, global_acl_bmp));
        
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_set_league_mode(lchip, league));
    }
    return ret;
}

int32
ctc_at_acl_get_league_mode(uint8 lchip, ctc_acl_league_t* league)
{
    uint8 lchip_start           = 0;
    uint8 lchip_end             = 0;
    uint8 all_lchip             = 1;
    uint16 pp_bmp               = 0;
    int32 ret                   = CTC_E_NONE;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(league);

    pp_bmp = SYS_PP_BMP_MAPPING(league->pp_bmp);
        
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_get_league_mode(lchip, league);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_ERROR_RETURN(sys_usw_acl_get_league_mode(lchip, league));
        break;
    }
    return ret;
}

int32
ctc_at_acl_reorder_entry(uint8 lchip, ctc_acl_reorder_t* reorder)
{
    uint8 lchip_start           = 0;
    uint8 lchip_end             = 0;
    uint8 all_lchip             = 1;
    uint16 pp_bmp               = 0;
    int32 ret                   = CTC_E_NONE;
    uint8 global_pp_en          = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(reorder);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, reorder->dir, reorder->acl_priority, &global_pp_en));

    pp_bmp = SYS_PP_BMP_MAPPING(reorder->pp_bmp);
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL)||global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_reorder_entry(lchip, reorder);
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_reorder_entry(lchip, reorder));
    }
    return ret;
}

int32
ctc_at_acl_replace_block(uint8 lchip, ctc_acl_replace_t* p_replace)
{
    uint8 lchip_start       = 0;
    uint8 lchip_end         = 0;
    uint8 all_lchip         = 1;
    uint16 pp_bmp           = 0;
    int32 ret               = CTC_E_NONE;
    uint8 global_pp_en      = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_ACL);
    LCHIP_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_replace);

    /* get global acl status */
    CTC_ERROR_RETURN(sys_usw_acl_get_pp_en_lkup_property(lchip, p_replace->dir, p_replace->src_lkup_level, &global_pp_en));
    
    pp_bmp = SYS_PP_BMP_MAPPING(p_replace->pp_bmp);
    if(!MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL) || global_pp_en)
    {
        lchip = SYS_PP_BASE(lchip);
        return sys_usw_acl_replace_block(lchip, p_replace);
    }
    
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start))
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_acl_replace_block(lchip, p_replace));
    }
    return ret;
}



